<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Hello world</title>
  <style>
  * {
    margin: 0;
    padding: 0;
  }

  .box {
    position: fixed;
    top: 50%;
    left: 50%;
    margin-top: -40vh;
    margin-left: -40vw;
    width: 80vw;
    height: 80vh;
    border: 1px solid #ccc;
  }

  .edit-wrapper {
    position: absolute;
    top: 0;
    left: 0;
    z-index: -10;
    opacity: 0;
    /*z-index: 10;
    opacity: 1;*/
    width: 100%;
    height: 100%;
    opacity: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden;
  }

  .edit-wrapper.is-show {
    z-index: 10;
    opacity: 1;
  }

  .edit-box {
    position: absolute;
    z-index: 10;
    opacity: 1;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    transform-origin: center;
  }

  .edit-box .close-btn {
    position: absolute;
    z-index: 50;
    top: 40px;
    right: 40px;
    text-align: center;
    width: 120px;
    height: 120px;
    line-height: 106px;
    border: 4px solid #fff;
    border-radius: 50%;
    font-size: 100px;
    cursor: pointer;
    color: #fff;
    box-sizing: content-box;
  }

  .edit-box .edit-box-container {
    position: relative;
    width: 100%;
    height: 100%;
  }

  .edit-line-drag-box {
    position: absolute;
    z-index: 10;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }

  .edit-line-drag-box .green {
    position: absolute;
    z-index: 5;
    background: green;
  }

  .edit-line-drag-box .black {
    position: absolute;
    z-index: 6;
    background: black;
  }

  .edit-line-drag-box .red-left,
  .edit-line-drag-box .red-right {
    position: absolute;
    z-index: 7;
    background: red;
  }

  .edit-line-drag-box .before,
  .edit-line-drag-box .after {
    position: absolute;
    top: 50%;
    margin-top: -7px;
    z-index: 10;
    width: 15px;
    height: 15px;
    cursor: e-resize;
  }

  .edit-line-drag-box .before {
    left: 0;
  }

  .edit-line-drag-box .after {
    right: 0;
  }

  .edit-line-drag-box .line {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    cursor: n-resize;
  }

  .edit-line-drag-box .xxb {
    position: absolute;
    z-index: 1;
    bottom: 10px;
    left: 0;
    right: 0;
    text-align: center;
    font-size: 120px;
    color: #409EFF;
  }

  .edit-rect-drag-box {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 10;
    width: 100%;
    height: 100%;
  }
  .edit-rect-drag-box .rect {
    position: absolute;
    top: 100px;
    left: 100px;
    z-index: 10;
    width: 100px;
    height: 100px;
    border: 8px solid red;
  }
  .edit-rect-drag-box .rect > div {
    position: absolute;
    z-index: 1;
  }
  .edit-rect-drag-box .rect .line-t {
    top: -8px;
    left: 0;
    right: 0;
    height: 8px;
    cursor: n-resize;
  }
  .edit-rect-drag-box .rect .line-r {
    top: 0;
    bottom: 0;
    right: -8px;
    width: 8px;
    cursor: e-resize;
  }
  .edit-rect-drag-box .rect .line-b {
    bottom: -8px;
    left: 0;
    right: 0;
    height: 8px;
    cursor: s-resize;
  }
  .edit-rect-drag-box .rect .line-l {
    bottom: 0;
    top: 0;
    left: -8px;
    width: 8px;
    cursor: w-resize;
  }

  .edit-box .edit-box-container .imageContainer {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .aa {
    width: 100%;
    height: 100%;
  }
  </style>
</head>

<body>
  <button onclick="showEditLineClick()">显示线</button>
  <button onclick="showEditRectClick()">显示矩形</button>
  <button onclick="okEditLine()">隐藏</button>
  <div class="box">
    <div class="aa"></div>
    <div class="edit-wrapper">
      <div class="edit-box">
        <div class="edit-box-container">
          <div class="close-btn" onclick="oEdit.close()">×</div>
          <div style="width:100%; height:100%;" class="imageContainer"></div>
          <div class="edit-rect-drag-box"></div>
          <div class="edit-line-drag-box">
            <div class="green">
              <div class="line" data-dis="y" data-key="lung_y" title="上下拖动"></div>
              <div class="before" data-dis="x" data-key="lung_x_begin" title="左右拖动"></div>
              <div class="after" data-dis="x" data-key="lung_x_end" title="左右拖动"></div>
            </div>
            <div class="black"></div>
            <div class="red-left">
              <div class="line" data-dis="y" data-key="heart_y_begin_left" title="上下拖动"></div>
              <div class="before" data-dis="x" data-key="heart_x_begin_left" title="左右拖动"></div>
            </div>
            <div class="red-right">
              <div class="line" data-dis="y" data-key="heart_y_end_right" title="上下拖动"></div>
              <div class="after" data-dis="x" data-key="heart_x_end_right" title="左右拖动"></div>
            </div>
            <div class="xxb"></div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
  <script src="./static/hammer.js"></script>
  <script src="./static/cornerstone.min.js"></script>
  <script src="./static/cornerstoneMath.min.js"></script>
  <script src="./static/cornerstoneWADOImageLoader.min.js"></script>
  <script src="./static/cornerstoneWebImageLoader.min.js"></script>
  <script src="./static/cornerstoneTools.min.js"></script>
  <script src="./static/dicomParser.min.js"></script>
  <script>
  const baseUrl = "http://127.0.0.1:8000/static/js/";

  var config = {
      "胸膜增厚": "rgb(255, 0, 255)",
      "纤维灶": "rgb(220, 20, 60)",
      "钙化": "rgb(148, 0, 211)",
      "骨折": "rgb(123, 104, 238)",
      "肺不张": "rgb(0, 0, 205)",
      "肿块": "rgb(30, 144, 255)",
      "结节": "rgb(184, 134, 11)",
      "肺气肿": "rgb(0, 139, 0)",
      "气胸": "rgb(139, 35, 35)",
      "PICC": "rgb(218, 165, 32)",
      "积液": "rgb(255, 140, 0)",
      "积气": "rgb(0, 0, 0)",
      "实变": "rgb(85, 107, 47)",
      "术后金属": "rgb(95, 158, 160)",
      "膈下游离气体": "rgb(9,113,175)",
      "肠道积气扩张": "rgb(4,248,194)",
      "肠道积液液平": "rgb(148, 0, 211)",
      "泌尿系统结石": "rgb(108,227,33)"

  }

  window.onload = function() {
    _initCornerstone();

    aaInitCornerstone();

    setTimeout(() => {
      oEdit.init();
    }, 1000);


    // oEdit.init();

    //  setTimeout(() => {
    //      oEdit.show({
    //          center_x: 1277,
    // heart_x_begin_left: 936,
    // heart_x_end_right: 2100,
    // heart_y_begin_left: 1531,
    // heart_y_end_right: 1621,
    // lung_x_begin: 170,
    // lung_x_end: 2348,
    // lung_y: 1565,
    // ratio: 0.5344,
    //      })
    //  }, 1500);
  }

  function _initCornerstone() {
    cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
    cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
    cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
    cornerstoneTools.external.cornerstone = cornerstone;
    cornerstoneTools.external.Hammer = Hammer;

    // Image Loader
    const config = {
      webWorkerPath: `${baseUrl}assets/image-loader/cornerstoneWADOImageLoaderWebWorker.js`,
      taskConfiguration: {
        decodeTask: {
          codecsPath: `${baseUrl}assets/image-loader/cornerstoneWADOImageLoaderCodecs.js`,
        },
      },
    };
    cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
  }

  // 初始化影像
  function aaInitCornerstone() {
    let element = document.querySelector('.aa');
    cornerstone.enable(element);
    cornerstone.loadAndCacheImage('wadouri:http://localhost:8088/static/data/1.2.840.1.19439.0.1000.20220101101114.1153.10000.3383340/1.2.840.113564.12312312360.2022010110184045329.1003000225002').then(function(image) {
      oEdit.setSize(image);
      var viewport = cornerstone.getDefaultViewportForImage(element, image);
      cornerstone.displayImage(element, image, viewport);
    });
  }

  // 显示编辑线
  function showEditLineClick() {
    oEdit.show('line', {
      center_x: 1277,
      heart_x_begin_left: 936,
      heart_x_end_right: 2100,
      heart_y_begin_left: 1531,
      heart_y_end_right: 1621,
      lung_x_begin: 170,
      lung_x_end: 2348,
      lung_y: 1565,
      ratio: 0.5344,
    })
  }

  // 显示编辑线
  function showEditRectClick() {
    oEdit.show('rect', [{"name": "纤维灶", "confidence": 0.681, "xmin": 941, "ymin": 1033, "xmax": 1355, "ymax": 1318}, {"name": "结节", "confidence": 0.272, "xmin": 1175, "ymin": 812, "xmax": 1241, "ymax": 877}, {"name": "实变", "confidence": 0.079, "xmin": 947, "ymin": 1030, "xmax": 1349, "ymax": 1294}, {"name": "结节", "confidence": 0.036, "xmin": 977, "ymin": 1032, "xmax": 1124, "ymax": 1182}])
  }

  // 确定
  function okEditLine() {
    oEdit.close();
  }

  /**
   * byte数组转换成base64 数据
   * @param {byte[]} buffer
   */
  function arrayBufferToBase64(buffer) {
    var binary = '';
    var bytes = new Uint8Array(buffer);
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
      binary += String.fromCharCode(bytes[i]);
    }
    return window.btoa(binary);
  }



  // 划线对象
  var oEdit = {
    visible: false,
    img: {
      w: 0,
      h: 0
    },
    ratio: '',
    
    editType: '', // 编辑类型，line线，rect方框

    // 数据
    oldData: null,
    newData: null,

    // 框的数据
    rectsize: 8,
    // 线
    linesize: 15,

    // canvas对象
    context: null,

    // 是否编辑过
    editGreen: false,
    editRedLeft: false,
    editRefRight: false,
    // 节点
    oEditWrapper: document.querySelector('.edit-wrapper'),
    oEditBox: document.querySelector('.edit-box'),
    oEditRectBox: document.querySelector('.edit-rect-drag-box'),
    oEditLneBox: document.querySelector('.edit-line-drag-box'),
    oContainer: null,
    oGreen: null,
    oBlack: null,
    oRedLeft: null,
    oRedRight: null,
    oXxb: null,
    // 是否已初始化事件
    isInited: false,
    // 移动
    move: {
      isdown: false,
      startCtr: null,
      key: '',
      dis: '',
      downx: 0,
      downy: 0,
    },
    setSize(image) {
      this.img.w = image.width;
      this.img.h = image.height;
      this.oEditBox.style.width = this.img.w + 'px';
      this.oEditBox.style.height = this.img.h + 'px';
    },

    show(type, data) {
      this.editType = type;
      this.oldData = JSON.parse(JSON.stringify(data));
      this.newData = JSON.parse(JSON.stringify(data));

      this.oEditRectBox.style.display = 'none';
      this.oEditLneBox.style.display = 'none';


      if(type == 'line') {
        this.drawLine();
        this.oEditLneBox.style.display = 'block';

        $(this.oEditWrapper).addClass('is-show');
        this.visible = true;
      } else if (type == 'rect') {
        this.initRect();
        setTimeout(() => {
          this.drawRect();
          this.oEditRectBox.style.display = 'block';

          $(this.oEditWrapper).addClass('is-show');
          this.visible = true;
        }, 100);
      }
    },
    save() {
      infos[image_uir + "ctr"] = this.newData;
      drawReload($('#ctr_select').is(':checked'));
      setXxb(this.newData.ratio);
      this.close();
    },
    close() {
      // $('#editBtn').text('编辑');
      $(this.oEditWrapper).removeClass('is-show');
      // $('#myNavbar > .nav').show();
      this.visible = false;
    },
    init() {
      if (this.isInited) {
        return;
      }
      this.isInited = true;
      // 节点
      this.oContainer = this.oEditBox.querySelector('.edit-box-container');
      this.oGreen = this.oEditBox.querySelector('.green');
      this.oBlack = this.oEditBox.querySelector('.black');
      this.oRedLeft = this.oEditBox.querySelector('.red-left');
      this.oRedRight = this.oEditBox.querySelector('.red-right');
      this.oXxb = this.oEditBox.querySelector('.xxb');
      this.oElement = this.oEditBox.querySelector('.imageContainer');
      // 矩形
      this.oRect = this.oEditBox.querySelector('.edit-rect-drag-box .rect');

      // 初始化影像
      this.initCornerstone();
      setTimeout(() => {
        this.setRatio();
      }, 500);

      // 初始化事件
      this.initEvent();
    },
    // 初始化影像
    initCornerstone() {
      var _this = this;
      cornerstone.enable(this.oElement);
      cornerstone.loadAndCacheImage('wadouri:http://localhost:8088/static/data/1.2.840.1.19439.0.1000.20220101101114.1153.10000.3383340/1.2.840.113564.12312312360.2022010110184045329.1003000225002').then(function(image) {

        var viewport = cornerstone.getDefaultViewportForImage(_this.oElement, image);
        cornerstone.displayImage(_this.oElement, image, viewport);
      });
    },

    // 初始化window移动
    initEvent() {
      var _this = this;
      var dom = $(this.oEditBox).find('.line, .before, .after');
      $(this.oEditBox).find('.line, .before, .after, .line-t, .line-r, .line-b, .line-l').on('mousedown', function(e) {
        _this.move.isdown = true;
        _this.move.startCtr = JSON.parse(JSON.stringify(_this.newData));
        _this.move.dis = e.target.dataset.dis;
        _this.move.key = e.target.dataset.key;
        _this.move.downx = e.pageX;
        _this.move.downy = e.pageY;
      })
      window.addEventListener('mousemove', function(e) {
        if (!_this.move.isdown) {
          return;
        }
        var movex = (e.pageX - _this.move.downx) / _this.ratio;
        var movey = (e.pageY - _this.move.downy) / _this.ratio;
        _this.saveDrag(movex, movey);
      })
      window.addEventListener('mouseup', function(e) {
        if (!_this.move.isdown) {
          return;
        }
        _this.move.isdown = false;
      })
    },

    initRect() {
      var html = '';
      console.log(this.newData)
      this.newData.forEach((item, index) => {
        html += `<div class="rect" data-dis="xy" data-index="${index}">
              <div class="line-t" data-dis="y" data-key="ymin" data-index="${index}"></div>
              <div class="line-r" data-dis="x" data-key="xmax" data-index="${index}"></div>
              <div class="line-b" data-dis="y" data-key="ymax" data-index="${index}"></div>
              <div class="line-l" data-dis="x" data-key="xmin" data-index="${index}"></div>
            </div>`;
      })
      this.oEditRectBox.innerHTML = html;
    },

    // 设置参数
    setRatio() {
      // 设置图片宽高
      var boxw = this.oEditWrapper.clientWidth,
        boxh = this.oEditWrapper.clientHeight;
      var min = Math.min(boxw, boxh);
      if (boxw / boxh >= this.img.w / this.img.h) {
        // 计算比例
        this.ratio = boxh / this.img.h;
      } else {
        // 计算比例
        this.ratio = boxw / this.img.w;
      }
      this.oEditBox.style.transform = `translate(-50%, -50%) scale(${this.ratio})`;
    },

    // 保存移动结果
    saveDrag(movex, movey) {
      // 改变值
      this.newData[this.move.key] = (this.move.dis == 'x' ? movex : movey) + this.move.startCtr[this.move.key];
      if(this.editType == 'line') {
        // 计算心胸比
        this.newData.ratio = (this.newData.heart_x_end_right - this.newData.heart_x_begin_left) / (this.newData.lung_x_end - this.newData.lung_x_begin);
        // 画内容
        this.drawLine();
      } else if (this.editType == 'rect') {
        // 画内容
        this.drawRect();
      }
    },

    // 画矩形
    drawRect() {
      var _this = this;
      this.newData.forEach((item, index) => {
        this.oEditRectBox.children[index].style.top = item.ymin+'px';
        this.oEditRectBox.children[index].style.left = item.xmin+'px';
        this.oEditRectBox.children[index].style.width = item.xmax-item.xmin+'px';
        this.oEditRectBox.children[index].style.height = item.ymax-item.ymin+'px';
        this.oEditRectBox.children[index].style.borderColor = config[item.name] || 'rgb(0, 0, 0)';
      })
    },

    // 绘制DOM
    drawLine() {
      var ctr = this.newData;
      // 绿色线
      this.oGreen.style.height = this.linesize + 'px';
      this.oGreen.style.left = ctr.lung_x_begin + 'px';
      this.oGreen.style.right = (this.img.w - ctr.lung_x_end) + 'px';
      this.oGreen.style.top = ctr.lung_y - this.linesize / 2 + 'px';

      var centerX = (ctr.lung_x_begin + ctr.lung_x_end) / 2
      var Y = [ctr.lung_y, ctr.heart_y_begin_left, ctr.heart_y_end_right]
      var minY = Math.min(...Y)
      var maxY = Math.max(...Y)

      // 黑色线
      this.oBlack.style.width = this.linesize + 'px';
      this.oBlack.style.left = centerX - this.linesize / 2 + 'px';
      this.oBlack.style.top = (minY - 50) + 'px';
      this.oBlack.style.bottom = (this.img.h - (maxY + 50)) + 'px';

      // 红色左
      this.oRedLeft.style.height = this.linesize + 'px';
      this.oRedLeft.style.left = ctr.heart_x_begin_left + 'px';
      this.oRedLeft.style.right = (this.img.w - centerX) + 'px';
      this.oRedLeft.style.top = ctr.heart_y_begin_left - this.linesize / 2 + 'px';

      // 红色右
      this.oRedRight.style.height = this.linesize + 'px';
      this.oRedRight.style.left = centerX + 'px';
      this.oRedRight.style.right = (this.img.w - ctr.heart_x_end_right) + 'px';
      this.oRedRight.style.top = ctr.heart_y_end_right - this.linesize / 2 + 'px';

      // 设置心胸比
      this.oXxb.innerHTML = '心胸比：' + ctr.ratio.toFixed(2);
    },
  }
  </script>
</body>

</html>